package cn.szq.springframework.context.annotation;

import cn.hutool.core.util.StrUtil;
import cn.szq.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import cn.szq.springframework.beans.factory.config.BeanDefinition;
import cn.szq.springframework.beans.factory.support.BeanDefinitionRegistry;
import cn.szq.springframework.stereotype.Component;

import java.util.Set;

/**
 * @ClassName: ClassPathBeanDefinitionScanner
 * @Description:
 * @Author: szq
 * @Date: 2021-09-18 16:09:52
 */
public class ClassPathBeanDefinitionScanner  extends ClassPathScanningCandidateComponentProvider{

    private BeanDefinitionRegistry registry;

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
        this.registry = registry;
    }

    public void doScan(String ...basePackages){
        for(String basePackage : basePackages){
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for(BeanDefinition beanDefinition : candidates){
                //解析bean的作用域 singleton,prototype
                String beanScope = resoleBeanScope(beanDefinition);
                if(StrUtil.isNotEmpty(beanScope)){
                    beanDefinition.setScope(beanScope);
                }
                registry.registerBeanDefinition(determineBeanName(beanDefinition), beanDefinition);
            }

            //注册处理注解的BeanPostProcessor
            registry.registerBeanDefinition("cn.szq.springframework.context.annotation.AutowiredAnnotationBeanPostProcessor", new BeanDefinition(AutowiredAnnotationBeanPostProcessor.class));

        }
    }

    private String determineBeanName(BeanDefinition beanDefinition) {
        Class<?> beanClass = beanDefinition.getBeanClass();
        Component component = beanClass.getAnnotation(Component.class);
        String value = component.value();
        if (StrUtil.isEmpty(value)) {
            value = StrUtil.lowerFirst(beanClass.getSimpleName());
        }
        return value;
    }

    private String resoleBeanScope(BeanDefinition beanDefinition) {
        Class<?> beanClass = beanDefinition.getBeanClass();
        Scope scope = beanClass.getAnnotation(Scope.class);
        if (null != scope){
            return scope.value();
        }
        return StrUtil.EMPTY;
    }
}
